//
//  Problem1870.swift
//  TestProject
//
//  Created by 武侠 on 2021/5/31.
//  Copyright © 2021 zhulong. All rights reserved.
//

import UIKit

/*
 1870. 准时到达的列车最小时速 未做完
 给你一个浮点数 hour ，表示你到达办公室可用的总通勤时间。要到达办公室，你必须按给定次序乘坐 n 趟列车。另给你一个长度为 n 的整数数组 dist ，其中 dist[i] 表示第 i 趟列车的行驶距离（单位是千米）。
 每趟列车均只能在整点发车，所以你可能需要在两趟列车之间等待一段时间。

 例如，第 1 趟列车需要 1.5 小时，那你必须再等待 0.5 小时，搭乘在第 2 小时发车的第 2 趟列车。
 返回能满足你准时到达办公室所要求全部列车的 最小正整数 时速（单位：千米每小时），如果无法准时到达，则返回 -1 。
 生成的测试用例保证答案不超过 10^7 ，且 hour 的 小数点后最多存在两位数字 。

 示例 1：
     输入：dist = [1,3,2], hour = 6
     输出：1
     解释：速度为 1 时：
     - 第 1 趟列车运行需要 1/1 = 1 小时。
     - 由于是在整数时间到达，可以立即换乘在第 1 小时发车的列车。第 2 趟列车运行需要 3/1 = 3 小时。
     - 由于是在整数时间到达，可以立即换乘在第 4 小时发车的列车。第 3 趟列车运行需要 2/1 = 2 小时。
     - 你将会恰好在第 6 小时到达。
 示例 2：
     输入：dist = [1,3,2], hour = 2.7
     输出：3
     解释：速度为 3 时：
     - 第 1 趟列车运行需要 1/3 = 0.33333 小时。
     - 由于不是在整数时间到达，故需要等待至第 1 小时才能搭乘列车。第 2 趟列车运行需要 3/3 = 1 小时。
     - 由于是在整数时间到达，可以立即换乘在第 2 小时发车的列车。第 3 趟列车运行需要 2/3 = 0.66667 小时。
     - 你将会在第 2.66667 小时到达。
 示例 3：
     输入：dist = [1,3,2], hour = 1.9
     输出：-1
     解释：不可能准时到达，因为第 3 趟列车最早是在第 2 小时发车。
 提示：
     n == dist.length
     1 <= n <= 10^5
     1 <= dist[i] <= 10^5
     1 <= hour <= 10^9
     hours 中，小数点后最多存在两位数字
 */
@objcMembers class Problem1870: NSObject {
    func solution() {
        print(minSpeedOnTime([1,3,2], 6))
        print(minSpeedOnTime([1,3,2], 2.7))
        print(minSpeedOnTime([1,3,2], 1.9))
        print(minSpeedOnTime([1,3,2], 4.9))
//        print(minSpeedOnTime([1,1,2,2,3], 6.4))
//        print(minSpeedOnTime([1,5,2,2,3], 8.4))
//        print(minSpeedOnTime([1,1,100000], 2.01))
    }
    
    /*
     二分法：
     首先确定left和right，也就是最慢的速度、最快的速度
     right：最快的速度，我们知道每个站点至少要1个小时，那么我们让最长的距离也花费一个小时就完成
     dist.max()/v = 1  =>  v=dist.max()
     left: 最慢的速度，我们让最长的距离，就花费了h个小时, 其他的就走不了
     dist.max()/v = h  =>  v=dist.max()/h
     1:
     */
    func minSpeedOnTime(_ dist: [Int], _ hour: Double) -> Int {
        if Double(dist.count - 1) > hour {
            return -1
        }
        let maxd = Double(dist.max()!)
        var l = maxd / hour, r = 1e7
        var mid:Double = 0
        var sum:Double = 0
        while l < r {
            mid = l + (r - l) / 2
            
            // 判断速度为mid时，需要花费的时间
            sum = 0
            for i in 0..<dist.count-1 {
                sum += (Double(dist[i]) + mid - 1) / mid
            }
            sum += Double(dist[dist.count-1]) / mid
            print(l, r, mid, sum)
            if sum > hour {     // 时间花超了，不满足了，速度得快点
                l = mid + 1
            } else {
                r = mid
            }
        }
        print(l, r, mid, sum)
        return Int(l)
    }
}
